package com.ruoyi.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.asms.controller.AsmsFaultConfirmStageController;
import com.ruoyi.asms.controller.AsmsFaultResolveStageController;
import com.ruoyi.asms.domain.AsmsFaultConfirmStage;
import com.ruoyi.asms.domain.AsmsFaultResolveStage;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.statistics.vo.LineChartVo;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.security.service.TokensService;

import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统设置模块数据统计分析Controller
 *
 * @author WJH
 * @date 2021-12-14
 */
@RestController
@RequestMapping("/system/SysDataStatistics")
public class SysDataStatisticsController {

    @Autowired
    private TokensService tokenService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysLoginInfoService loginInfoService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private ReUsingService reUsingService;
    @Autowired
    private ISysDataStatisticsService sysDataStatisticsService;
  //  @Autowired
 //   private RemoteAsmsService remoteAsmsService;
    @Autowired
    private AsmsFaultConfirmStageController faultConfirmStageController;

    @Autowired
    private AsmsFaultResolveStageController faultReportStageController;

    @PreAuthorize
    @GetMapping("/getMyDeptUserNum")
    @ApiOperation("获取本部门的用户数量")
    public com.ruoyi.common.core.web.domain.AjaxResult getMyDeptUserNum() {
        //获取当前部门的id
        Long deptId = tokenService.getLoginUser().getDeptid();
        long count = userService.count(new QueryWrapper<SysUser>().eq(SysUser.DEPT_ID, deptId));
        return com.ruoyi.common.core.web.domain.AjaxResult.success(count);
    }

    @PreAuthorize
    @GetMapping("/getAllUserNum")
    @ApiOperation("获取系统所有用户的数量")
    public com.ruoyi.common.core.web.domain.AjaxResult getAllUserNum() {
        long allUserNum = userService.count();
        return com.ruoyi.common.core.web.domain.AjaxResult.success(allUserNum);
    }

    @PreAuthorize
    @PostMapping(value="/export", produces = "application/octet-stream")
    @ApiOperation("导出用户信息")
    public void export(HttpServletResponse response) throws IOException {
        //构造一个部门map，用于在循环中查询
        List<SysDept> deptList = deptService.list();
        HashMap<Long, SysDept> deptListMap = new HashMap<>();
        deptList.forEach(item -> deptListMap.put(item.getDeptId(), item));

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        //系统管理员导出所有用户数据、其他用户导出本部门的用户数据
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            Long deptId = tokenService.getLoginUser().getDeptid();
            wrapper.eq(SysUser.DEPT_ID, deptId);
        }
        List<SysUser> sysUsers = userService.list(wrapper);
        List<ExportUserVo> exportUserVos = new ArrayList<>();
        for (SysUser sysUser : sysUsers) {
            ExportUserVo exportUserVo = new ExportUserVo();
            BeanUtils.copyProperties(sysUser, exportUserVo);
            SysDept sysDept = deptListMap.get(sysUser.getDeptId());
            if (sysDept != null) {
                exportUserVo.setDeptName(sysDept.getDeptFullName());
            }
            if (StringUtils.isNotEmpty(sysUser.getUserName())) {
                exportUserVos.add(exportUserVo);
            }
        }
        ExcelUtil<ExportUserVo> excelUtil = new ExcelUtil<>(ExportUserVo.class);
        excelUtil.exportExcel(response, exportUserVos, "用户数据");
    }

    @PreAuthorize
    @GetMapping("/getSysVisitNum")
    @ApiOperation("获取系统访问量")
    public R<List<LineChartVo>> getSysVisitNum(@ApiParam("日期范围:最近一年year、最近一季season、最近一月month、最近一周week")
                                         @RequestParam(value = "dateScope", required = false) String dateScope,
                                               @ApiParam("周期:日day、周week、月month")
                                         @RequestParam(value = "period", required = false) String period) {
        List<LineChartVo> lineChartVos = new ArrayList<>();
        List<VisitNumVo> visitNumVoList = new ArrayList<>();
        List<String> dates = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (dateScope != null && period != null) {
            switch (dateScope) {
                case "year": {
                    calendar.add(Calendar.YEAR, -1);
                    Long ms = calendar.getTime().getTime();
                    if (period.equals("month")) {
                        //最近一年的每个月
                        visitNumVoList = loginInfoService.getVisitNum("%y年%m月", ms);
                        dates = reUsingService.getRecentOneYearMonth();
                    } else if (period.equals("week")) {
                        //最近一年的每个周
                        visitNumVoList = loginInfoService.getVisitNum("%y年第%v周", ms);
                        dates = reUsingService.getWeeks(52);
                    }
                    break;
                }
                case "season": {
                    calendar.add(Calendar.MONTH, -3);
                    Long ms = calendar.getTime().getTime();
                    if (period.equals("week")) {
                        //最近一季的每个周
                        visitNumVoList = loginInfoService.getVisitNum("%y年第%v周", ms);
                        dates = reUsingService.getWeeks(13);
                    } else if (period.equals("day")) {
                        //最近一季的每天
                        visitNumVoList = loginInfoService.getVisitNum("%m月%d日", ms);
                        dates = reUsingService.getDays(92);
                    }
                    break;
                }
                case "month": {
                    calendar.add(Calendar.MONTH, -1);
                    Long ms = calendar.getTime().getTime();
                    if (period.equals("week")) {
                        //最近一月的每周
                        visitNumVoList = loginInfoService.getVisitNum("%y年第%v周", ms);
                        dates = reUsingService.getWeeks(4);
                    } else if (period.equals("day")) {
                        //最近一月的每天
                        visitNumVoList = loginInfoService.getVisitNum("%m月%d日", ms);
                        dates = reUsingService.getDays(31);
                    }
                    break;
                }
                case "week": {
                    calendar.add(Calendar.DATE, -6);
                    Long ms = calendar.getTime().getTime();
                    if (period.equals("day")) {
                        //最近一周的每天
                        visitNumVoList = loginInfoService.getVisitNum("%m月%d日", ms);
                        dates = reUsingService.getDays(7);
                    }
                    break;
                }
            }
        } else {
            //默认展示最近一周的每天
            calendar.add(Calendar.DATE, -6);
            Long ms = calendar.getTime().getTime();
            visitNumVoList = loginInfoService.getVisitNum("%m月%d日", ms);
            dates = reUsingService.getDays(7);
        }
        if (dates.size() != 0) {
            //将日期调整为有序且连续的
            HashMap<String, Integer> map = new HashMap<>();
            visitNumVoList.forEach(item -> map.put(item.getDate(), item.getCount()));
            for (String day : dates) {
                com.ruoyi.common.core.domain.statistics.vo.LineChartVo vo = new com.ruoyi.common.core.domain.statistics.vo.LineChartVo();
                vo.setTitle(day);
                vo.setValue(map.get(day) != null ? Long.valueOf(map.get(day)) : 0L);
                lineChartVos.add(vo);
            }
            return R.ok(lineChartVos);
        }
        //往折线图列表中添加数据
        for (VisitNumVo visitNumVo : visitNumVoList) {
            com.ruoyi.common.core.domain.statistics.vo.LineChartVo lineChartVo = new com.ruoyi.common.core.domain.statistics.vo.LineChartVo();
            lineChartVo.setTitle(visitNumVo.getDate());
            lineChartVo.setValue(Long.valueOf(visitNumVo.getCount()));
            lineChartVos.add(lineChartVo);
        }
        return R.ok(lineChartVos);
    }

    @ApiOperation(value = "学校入驻情况：公司查看")
    @GetMapping("/deptJoinLookByCompany")
    public R<List<DeptJoinVo>> deptJoinLookByCompany() {
        List<DeptJoinVo> deptJoinVos = sysDataStatisticsService.deptJoin("company");
        return R.ok(deptJoinVos);
    }

    @ApiOperation("分类学校入驻情况：公司查看")
    @GetMapping("/deptJoinWithTypeLookByCompany")
    public R<List<DeptJoinWithTypeVo>> deptJoinWithTypeLookByCompany() {
        List<DeptJoinWithTypeVo> deptJoinWithTypeVos = sysDataStatisticsService.deptJoinWithType("company");
        return R.ok(deptJoinWithTypeVos);
    }

    @ApiOperation("累计学校入驻数量：公司查看")
    @GetMapping("/deptJoinNumLookByCompany")
    public com.ruoyi.common.core.web.domain.AjaxResult deptJoinNumLookByCompany() {
        Integer deptJoinNum = sysDataStatisticsService.deptJoinNum("company");
        return com.ruoyi.common.core.web.domain.AjaxResult.success(deptJoinNum);
    }

    @ApiOperation("本月学校签约情况：公司查看")
    @GetMapping("/thisMonthDeptSignLookByCompany")
    public com.ruoyi.common.core.web.domain.AjaxResult thisMonthDeptSignLookByCompany() {

        return com.ruoyi.common.core.web.domain.AjaxResult.success();
    }

    @ApiOperation("当月所有用户变动情况：公司查看")
    @GetMapping("/thisMonthAllUserChangeLookByCompany")
    public com.ruoyi.common.core.web.domain.AjaxResult thisMonthAllUserChangeLookByCompany() {

        return com.ruoyi.common.core.web.domain.AjaxResult.success();
    }

    @ApiOperation("当月学校用户变动情况：公司查看")
    @GetMapping("/thisMonthDeptUserChangeLookByCompany")
    public R<List<ThisMonthDeptUserChangeVo>> thisMonthDeptUserChangeLookByCompany() {
        return R.ok(sysDataStatisticsService.thisMonthDeptUserChange());
    }

    @ApiOperation("业务分布情况：公司查看")
    @GetMapping("/businessAreaLookByCompany")
    public R<List<BusinessAreaVo>> businessAreaLookByCompany() {
        return R.ok(sysDataStatisticsService.businessArea());
    }

    @ApiOperation("获取小程序首页系统动态")
    @GetMapping("/getMpSysTrends")
    public com.ruoyi.common.core.web.domain.AjaxResult getMpSysTrends() {
        List<String> result = new ArrayList<>();
        List<MpSysTrendsVo> tempList = new ArrayList<>();

        List<SysUser> users = userService.list(new QueryWrapper<SysUser>()
                .select(SysUser.NICK_NAME, SysUser.USER_ID, SysUser.CREATE_TIME)
                .isNotNull(SysUser.NICK_NAME).ne(SysUser.NICK_NAME, "").orderByDesc(SysUser.USER_ID));
        Map<Long, SysUser> userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, o -> o));

        //用户最新的10条入驻信息
        List<SysUser> newUsers = users.stream().limit(10).collect(Collectors.toList());
        newUsers.forEach(item -> {
            MpSysTrendsVo vo = new MpSysTrendsVo();
            String userName = item.getNickName().substring(0, 1);
            vo.setContent("系统消息：" + userName + "**加入了本系统");
            vo.setTime(item.getCreateTime());
            tempList.add(vo);
        });

        //用户最新的10条评论
        R<List<AsmsFaultConfirmStage>> r1 = faultConfirmStageController.getLatestComments();
        if (r1.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException(r1.getMsg());
        r1.getData().forEach(c -> {
            MpSysTrendsVo vo = new MpSysTrendsVo();
            SysUser user = userMap.get(c.getConfirmUserId());
            String hiddenName = "";
            if (user != null)
                hiddenName = user.getNickName().substring(0, 1);
            else
                hiddenName = "用户";
            vo.setContent(hiddenName + "**：" + c.getEvaluationContent());
            vo.setTime(c.getEndTime());
            tempList.add(vo);
        });

        //技术人员最新的10条故障处理信息
        R<List<AsmsFaultResolveStage>> r2 = faultReportStageController.getLatestFaultResovle();
        if (r2.getCode() == R.FAIL)
            throw new com.ruoyi.common.core.exception.ServiceException(r2.getMsg());
        r2.getData().forEach(r -> {
            MpSysTrendsVo vo = new MpSysTrendsVo();
            String hiddenName = userMap.get(r.getFaultResolveUserId()).getNickName().substring(0, 1);
            vo.setContent(hiddenName + "师傅处理了【" + r.getFaultAssetName() + "】的故障");
            vo.setTime(r.getEndTime());
            tempList.add(vo);
        });

        //按各自的创建时间降序
        tempList.sort(Comparator.comparing(MpSysTrendsVo::getTime).reversed());

        tempList.forEach(t -> result.add(t.getContent()));

        return com.ruoyi.common.core.web.domain.AjaxResult.success(result);
    }
}
